home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / SYSLOG.PY < prev    next >
Encoding:
Text File  |  2000-05-12  |  8.6 KB  |  239 lines

  1. # -*- Mode: Python; tab-width: 4 -*-
  2.  
  3. # From: "Samual M. Rushing" <rushing@nightmare.com>
  4. # Date: Mon, 21 Apr 1997 16:10:42 -0500
  5.  
  6. # ======================================================================
  7. # Copyright 1997 by Sam Rushing
  8. #                         All Rights Reserved
  9. # Permission to use, copy, modify, and distribute this software and
  10. # its documentation for any purpose and without fee is hereby
  11. # granted, provided that the above copyright notice appear in all
  12. # copies and that both that copyright notice and this permission
  13. # notice appear in supporting documentation, and that the name of Sam
  14. # Rushing not be used in advertising or publicity pertaining to
  15. # distribution of the software without specific, written prior
  16. # permission.
  17. # SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  18. # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
  19. # NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  20. # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  21. # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  22. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  23. # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  24. # ======================================================================
  25.  
  26. """socket interface to unix syslog.
  27. On Unix, there are usually two ways of getting to syslog: via a
  28. local unix-domain socket, or via the TCP service.
  29.  
  30. Usually "/dev/log" is the unix domain socket.  This may be different
  31. for other systems.
  32.  
  33. >>> my_client = syslog_client ('/dev/log')
  34.  
  35. Otherwise, just use the UDP version, port 514.
  36.  
  37. >>> my_client = syslog_client (('my_log_host', 514))
  38.  
  39. On win32, you will have to use the UDP version.  Note that
  40. you can use this to log to other hosts (and indeed, multiple
  41. hosts).
  42.  
  43. This module is not a drop-in replacement for the python
  44. <syslog> extension module - the interface is different.
  45.  
  46. Usage:
  47.  
  48. >>> c = syslog_client()
  49. >>> c = syslog_client ('/strange/non_standard_log_location')
  50. >>> c = syslog_client (('other_host.com', 514))
  51. >>> c.log ('testing', facility='local0', priority='debug')
  52.  
  53. """
  54.  
  55. # TODO: support named-pipe syslog.
  56. # [see ftp://sunsite.unc.edu/pub/Linux/system/Daemons/syslog-fifo.tar.z]
  57.  
  58. # from <linux/sys/syslog.h>:
  59. # ===========================================================================
  60. # priorities/facilities are encoded into a single 32-bit quantity, where the
  61. # bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
  62. # (0-big number).  Both the priorities and the facilities map roughly
  63. # one-to-one to strings in the syslogd(8) source code.  This mapping is
  64. # included in this file.
  65. #
  66. # priorities (these are ordered)
  67.  
  68. LOG_EMERG       = 0     #  system is unusable 
  69. LOG_ALERT       = 1     #  action must be taken immediately 
  70. LOG_CRIT        = 2     #  critical conditions 
  71. LOG_ERR         = 3     #  error conditions 
  72. LOG_WARNING     = 4     #  warning conditions 
  73. LOG_NOTICE      = 5     #  normal but significant condition 
  74. LOG_INFO        = 6     #  informational 
  75. LOG_DEBUG       = 7     #  debug-level messages 
  76.  
  77. #  facility codes 
  78. LOG_KERN        = 0     #  kernel messages 
  79. LOG_USER        = 1     #  random user-level messages 
  80. LOG_MAIL        = 2     #  mail system 
  81. LOG_DAEMON      = 3     #  system daemons 
  82. LOG_AUTH        = 4     #  security/authorization messages 
  83. LOG_SYSLOG      = 5     #  messages generated internally by syslogd 
  84. LOG_LPR         = 6     #  line printer subsystem 
  85. LOG_NEWS        = 7     #  network news subsystem 
  86. LOG_UUCP        = 8     #  UUCP subsystem 
  87. LOG_CRON        = 9     #  clock daemon 
  88. LOG_AUTHPRIV    = 10    #  security/authorization messages (private) 
  89.  
  90. #  other codes through 15 reserved for system use 
  91. LOG_LOCAL0      = 16        #  reserved for local use 
  92. LOG_LOCAL1      = 17        #  reserved for local use 
  93. LOG_LOCAL2      = 18        #  reserved for local use 
  94. LOG_LOCAL3      = 19        #  reserved for local use 
  95. LOG_LOCAL4      = 20        #  reserved for local use 
  96. LOG_LOCAL5      = 21        #  reserved for local use 
  97. LOG_LOCAL6      = 22        #  reserved for local use 
  98. LOG_LOCAL7      = 23        #  reserved for local use 
  99.  
  100. priority_names = {
  101.     "alert":    LOG_ALERT,
  102.     "crit":     LOG_CRIT,
  103.     "debug":    LOG_DEBUG,
  104.     "emerg":    LOG_EMERG,
  105.     "err":      LOG_ERR,
  106.     "error":    LOG_ERR,        #  DEPRECATED 
  107.     "info":     LOG_INFO,
  108.     "notice":   LOG_NOTICE,
  109.     "panic":    LOG_EMERG,      #  DEPRECATED 
  110.     "warn":     LOG_WARNING,        #  DEPRECATED 
  111.     "warning":  LOG_WARNING,
  112.     }
  113.  
  114. facility_names = {
  115.     "auth":     LOG_AUTH,
  116.     "authpriv": LOG_AUTHPRIV,
  117.     "cron":     LOG_CRON,
  118.     "daemon":   LOG_DAEMON,
  119.     "kern":     LOG_KERN,
  120.     "lpr":      LOG_LPR,
  121.     "mail":     LOG_MAIL,
  122.     "news":     LOG_NEWS,
  123.     "security": LOG_AUTH,       #  DEPRECATED 
  124.     "syslog":   LOG_SYSLOG,
  125.     "user":     LOG_USER,
  126.     "uucp":     LOG_UUCP,
  127.     "local0":   LOG_LOCAL0,
  128.     "local1":   LOG_LOCAL1,
  129.     "local2":   LOG_LOCAL2,
  130.     "local3":   LOG_LOCAL3,
  131.     "local4":   LOG_LOCAL4,
  132.     "local5":   LOG_LOCAL5,
  133.     "local6":   LOG_LOCAL6,
  134.     "local7":   LOG_LOCAL7,
  135.     }
  136.  
  137. import socket
  138.  
  139. class syslog_client:
  140.     def __init__ (self, address='/dev/log'):
  141.         self.address = address
  142.         if type (address) == type(''):
  143.             try: # APUE 13.4.2 specifes /dev/log as datagram socket
  144.                 self.socket = socket.socket( socket.AF_UNIX
  145.                                                        , socket.SOCK_DGRAM)
  146.                 self.socket.connect (address)
  147.             except: # older linux may create as stream socket
  148.                 self.socket = socket.socket( socket.AF_UNIX
  149.                                                        , socket.SOCK_STREAM)
  150.                 self.socket.connect (address)
  151.             self.unix = 1
  152.         else:
  153.             self.socket = socket.socket( socket.AF_INET
  154.                                                    , socket.SOCK_DGRAM)
  155.             self.unix = 0
  156.  
  157.     # curious: when talking to the unix-domain '/dev/log' socket, a
  158.     #   zero-terminator seems to be required.  this string is placed
  159.     #   into a class variable so that it can be overridden if
  160.     #   necessary.
  161.  
  162.     log_format_string = '<%d>%s\000'
  163.  
  164.     def log (self, message, facility=LOG_USER, priority=LOG_INFO):
  165.         message = self.log_format_string % (
  166.             self.encode_priority (facility, priority),
  167.             message
  168.             )
  169.         if self.unix:
  170.             self.socket.send (message)
  171.         else:
  172.             self.socket.sendto (message, self.address)
  173.  
  174.     def encode_priority (self, facility, priority):
  175.         if type(facility) == type(''):
  176.             facility = facility_names[facility]
  177.         if type(priority) == type(''):
  178.             priority = priority_names[priority]         
  179.         return (facility<<3) | priority
  180.  
  181.     def close (self):
  182.         if self.unix:
  183.             self.socket.close()
  184.  
  185. if __name__ == '__main__':
  186.     """
  187.        Unit test for syslog_client.  Set up for the test by:
  188.     
  189.     * tail -f /var/log/allstuf (to see the "normal" log messages).
  190.  
  191.         * Running the test_logger.py script with a junk file name (which
  192.       will be opened as a Unix-domain socket). "Custom" log messages
  193.       will go here.
  194.  
  195.     * Run this script, passing the same junk file name.
  196.  
  197.     * Check that the "bogus" test throws, and that none of the rest do.
  198.  
  199.     * Check that the 'default' and 'UDP' messages show up in the tail.
  200.  
  201.     * Check that the 'non-std' message shows up in the test_logger
  202.       console.
  203.  
  204.     * Finally, kill off the tail and test_logger, and clean up the
  205.       socket file.
  206.     """
  207.     import sys, traceback
  208.  
  209.     if len( sys.argv ) != 2:
  210.        print "Usage: syslog.py localSocketFilename"
  211.        sys.exit()
  212.  
  213.     def test_client( desc, address=None ):
  214.         try:
  215.             if address:
  216.                 client = syslog_client( address )
  217.             else:
  218.                 client = syslog_client()
  219.         except:
  220.             print 'syslog_client() [%s] ctor threw' % desc
  221.             traceback.print_exc()
  222.             return
  223.  
  224.         try:
  225.             client.log( 'testing syslog_client() [%s]' % desc
  226.                       , facility='local0', priority='debug' )
  227.             print 'syslog_client.log() [%s] did not throw' % desc
  228.         except:
  229.             print 'syslog_client.log() [%s] threw' % desc
  230.             traceback.print_exc()
  231.  
  232.     test_client( 'default' )
  233.     test_client( 'bogus file', '/some/bogus/logsocket' )
  234.     test_client( 'nonstd file', sys.argv[1] )
  235.     test_client( 'UDP',  ('localhost', 514) )
  236.